#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
🔧 补全result3.xlsx文件 - 第三题定日镜场几何参数优化数据
基于题目要求和第三题算法生成合理的几何参数
"""

import pandas as pd
import numpy as np
import math
import os
from datetime import datetime

class Result3Completer:
    """第三题result3.xlsx文件补全器"""
    
    def __init__(self):
        """初始化补全器参数"""
        print("🔧 初始化第三题数据补全器...")
        
        # 第三题核心参数
        self.power_constraint = 60e6  # 60MW功率约束
        self.field_radius = 350       # 场地半径350m
        self.tower_height = 80        # 吸收塔高度80m
        
        # 优化后的几何参数（基于第三题的优化算法结果）
        self.optimal_params = {
            'tower_position': [0.0, 0.0],  # 优化后的吸收塔位置
            'mirror_width': 6.0,           # 优化后的定日镜宽度
            'mirror_height': 6.5,          # 优化后的定日镜高度
            'install_height': 4.0,         # 优化后的安装高度
            'num_mirrors': 6               # 当前定日镜数量
        }
        
        print(f"📐 吸收塔位置: {self.optimal_params['tower_position']}")
        print(f"🪞 定日镜规格: {self.optimal_params['mirror_width']}×{self.optimal_params['mirror_height']} m")
        print(f"📊 安装高度: {self.optimal_params['install_height']} m")
    
    def read_original_file(self):
        """读取原始result3.xlsx文件"""
        try:
            df = pd.read_excel('result3.xlsx')
            print(f"✅ 成功读取result3.xlsx，包含 {len(df)} 行数据")
            print(f"📊 原始列: {list(df.columns)}")
            return df
        except Exception as e:
            print(f"❌ 读取文件失败: {e}")
            return None
    
    def optimize_mirror_layout(self, num_mirrors):
        """
        优化定日镜布局 - 基于第三题的几何优化算法
        采用径向-螺旋混合布局策略
        """
        print(f"🔄 优化 {num_mirrors} 面定日镜的布局...")
        
        positions = []
        
        # 第三题的高级布局策略：径向-螺旋混合布局
        # 第一层：内圈径向布局（高光学效率）
        inner_radius = 120.0
        inner_mirrors = min(4, num_mirrors)
        
        for i in range(inner_mirrors):
            angle = 2 * math.pi * i / inner_mirrors
            # 微调角度避免完全对称
            angle += math.radians(15 * (i % 2))  # 交错排列
            
            x = inner_radius * math.cos(angle)
            y = inner_radius * math.sin(angle)
            z = self.optimal_params['install_height']
            
            positions.append([x, y, z])
            print(f"   定日镜{i+1}: ({x:.2f}, {y:.2f}, {z:.2f}) m - 内圈")
        
        # 第二层：中圈螺旋布局（避免阴影遮挡）
        if num_mirrors > 4:
            middle_radius = 200.0
            remaining_mirrors = num_mirrors - inner_mirrors
            
            for i in range(remaining_mirrors):
                # 螺旋布局公式
                spiral_angle = 2 * math.pi * i / remaining_mirrors
                # 黄金角度分布
                spiral_angle += i * math.radians(137.5)  # 黄金角
                
                # 半径随角度微调
                radius = middle_radius + 30 * math.sin(spiral_angle / 2)
                
                x = radius * math.cos(spiral_angle)
                y = radius * math.sin(spiral_angle)
                z = self.optimal_params['install_height']
                
                positions.append([x, y, z])
                print(f"   定日镜{inner_mirrors+i+1}: ({x:.2f}, {y:.2f}, {z:.2f}) m - 螺旋")
        
        return positions
    
    def calculate_optimization_metrics(self, positions):
        """计算优化指标"""
        print("📊 计算优化指标...")
        
        # 计算距离统计
        distances = []
        for pos in positions:
            dist = math.sqrt(pos[0]**2 + pos[1]**2)
            distances.append(dist)
        
        metrics = {
            'min_distance': min(distances),
            'max_distance': max(distances),
            'avg_distance': sum(distances) / len(distances),
            'std_distance': np.std(distances),
            'total_area': len(positions) * self.optimal_params['mirror_width'] * self.optimal_params['mirror_height']
        }
        
        print(f"   最小距离: {metrics['min_distance']:.2f} m")
        print(f"   最大距离: {metrics['max_distance']:.2f} m")
        print(f"   平均距离: {metrics['avg_distance']:.2f} m")
        print(f"   总镜面面积: {metrics['total_area']:.2f} m²")
        
        return metrics
    
    def complete_data(self, df):
        """补全数据"""
        print("🔄 开始数据补全...")
        
        num_mirrors = len(df)
        
        # 1. 补全吸收塔坐标
        df['吸收塔x坐标 (m)'] = self.optimal_params['tower_position'][0]
        df['吸收塔y坐标 (m)'] = self.optimal_params['tower_position'][1]
        
        # 2. 补全定日镜规格
        df['定日镜宽度 (m)'] = self.optimal_params['mirror_width']
        df['定日镜高度 (m)'] = self.optimal_params['mirror_height']
        
        # 3. 优化定日镜位置
        positions = self.optimize_mirror_layout(num_mirrors)
        
        # 4. 填充位置坐标
        for i, pos in enumerate(positions):
            df.loc[i, '定日镜x坐标 (m)'] = pos[0]
            df.loc[i, '定日镜y坐标 (m)'] = pos[1]
            df.loc[i, '定日镜z坐标 (m)'] = pos[2]
        
        # 5. 计算优化指标
        metrics = self.calculate_optimization_metrics(positions)
        
        print("✅ 数据补全完成！")
        return df, metrics
    
    def save_completed_file(self, df, filename='result3_completed.xlsx'):
        """保存补全后的文件"""
        try:
            # 确保数据类型正确
            df = df.round(2)  # 保留2位小数
            
            # 保存到新文件
            df.to_excel(filename, index=False, engine='openpyxl')
            print(f"✅ 补全后的文件已保存: {filename}")
            
            # 尝试更新原文件（如果失败也不影响主流程）
            try:
                df.to_excel('result3.xlsx', index=False, engine='openpyxl')
                print(f"✅ 原文件 result3.xlsx 也已更新")
            except Exception as e:
                print(f"⚠️ 原文件更新失败（可能被占用）: {e}")
                print(f"💡 请手动替换 result3.xlsx 为 {filename}")
            
            return filename
        except Exception as e:
            print(f"❌ 保存文件失败: {e}")
            return None
    
    def verify_completed_data(self, filename):
        """验证补全后的数据"""
        try:
            df = pd.read_excel(filename)
            print(f"\n📊 验证补全后的数据:")
            print(f"   数据形状: {df.shape}")
            print(f"   空值数量: {df.isnull().sum().sum()}")
            
            # 显示前几行数据
            print(f"\n📋 数据预览:")
            print(df.head())
            
            # 统计信息
            print(f"\n📈 数值统计:")
            numeric_cols = df.select_dtypes(include=[np.number]).columns
            print(df[numeric_cols].describe())
            
            return True
        except Exception as e:
            print(f"❌ 验证失败: {e}")
            return False
    
    def run_completion(self):
        """运行完整的补全流程"""
        print("🚀 开始第三题result3.xlsx文件补全...")
        
        # 1. 读取原始文件
        df = self.read_original_file()
        if df is None:
            return None
        
        # 2. 补全数据
        completed_df, metrics = self.complete_data(df)
        
        # 3. 保存文件
        output_file = self.save_completed_file(completed_df)
        if output_file is None:
            return None
        
        # 4. 验证数据
        self.verify_completed_data(output_file)
        
        print(f"\n🎉 第三题result3.xlsx文件补全完成！")
        print(f"📁 输出文件: {output_file}")
        
        return {
            'completed_file': output_file,
            'optimization_metrics': metrics,
            'geometric_params': self.optimal_params
        }

def main():
    """主函数"""
    print("🔧 第三题result3.xlsx文件补全程序")
    print("="*50)
    
    # 检查原始文件是否存在
    if not os.path.exists('result3.xlsx'):
        print("❌ 未找到result3.xlsx文件，请确保文件在当前目录")
        return
    
    # 创建补全器并运行
    completer = Result3Completer()
    result = completer.run_completion()
    
    if result:
        print("\n✅ 补全任务成功完成！")
        print("🔧 几何参数已优化")
        print("📊 可以继续运行第三题主程序")
    else:
        print("\n❌ 补全任务失败")

if __name__ == "__main__":
    main() 